package com.example.mqttclient;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Switch;
import android.widget.TextView;

import com.example.mqttclient.mqtt.MqttService;
import com.example.mqttclient.protocol.AirConfitioningMesssage;
import com.example.mqttclient.protocol.BoolMessage;
import com.example.mqttclient.protocol.FloatMessage;
import com.example.mqttclient.protocol.IntMessage;
import com.google.gson.Gson;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;

import org.eclipse.paho.client.mqttv3.MqttException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class DevicesDemoActivity extends AppCompatActivity implements MqttService.MqttEventCallBack, CompoundButton.OnCheckedChangeListener {

    private TextView connectState, temperatureValue, humidtyValue, pmValue, gasValue, doorStatus;
    private EditText airCconditioningValue;
    private MqttService.MqttBinder mqttBinder;
    private String TAG = "MainActivity";
    private Switch parlourlightSwitch, curtain_switch, fan_socket_switch, air_conditioning_switch;
    private Map<String, Integer> subscribeTopics = new HashMap<>();
    private LineChart lineChart;
    private LineData lineData;
    private LineDataSet temperatureDataSet, humidityDataSet, pmDataSet;

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mqttBinder = (MqttService.MqttBinder) iBinder;
            mqttBinder.setMqttEventCallBack(DevicesDemoActivity.this);
            if (mqttBinder.isConnected()) {
                connectState.setText("已连接");
                subscribeTopics();
            } else {
                connectState.setText("未连接");
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_devices_demo);
        connectState = findViewById(R.id.dev_connect_state);
        Intent mqttServiceIntent = new Intent(this, MqttService.class);

        bindService(mqttServiceIntent, connection, Context.BIND_AUTO_CREATE);
        temperatureValue = findViewById(R.id.temperature_value);
        humidtyValue = findViewById(R.id.humidity_value);
        pmValue = findViewById(R.id.pm_value);
        gasValue = findViewById(R.id.gas_value);
        doorStatus = findViewById(R.id.door_status);

        airCconditioningValue = findViewById(R.id.air_conditioning_value);
        parlourlightSwitch = findViewById(R.id.parlour_light_switch);
        parlourlightSwitch.setOnCheckedChangeListener(this);
        curtain_switch = findViewById(R.id.curtain_switch);
        curtain_switch.setOnCheckedChangeListener(this);
        fan_socket_switch = findViewById(R.id.fan_socket_switch);
        fan_socket_switch.setOnCheckedChangeListener(this);
        air_conditioning_switch = findViewById(R.id.air_conditioning_switch);
        air_conditioning_switch.setOnCheckedChangeListener(this);

        lineChart = findViewById(R.id.line_chart);
        setupLineChart();

        // Add test data
        addTestData();
    }

    private void setupLineChart() {
        temperatureDataSet = new LineDataSet(new ArrayList<>(), "温度");
        humidityDataSet = new LineDataSet(new ArrayList<>(), "湿度");
        pmDataSet = new LineDataSet(new ArrayList<>(), "PM2.5");

        lineData = new LineData(temperatureDataSet, humidityDataSet, pmDataSet);
        lineChart.setData(lineData);

        XAxis xAxis = lineChart.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        YAxis leftAxis = lineChart.getAxisLeft();
        lineChart.getAxisRight().setEnabled(false);

        temperatureDataSet.setColor(android.graphics.Color.RED);
        humidityDataSet.setColor(android.graphics.Color.BLUE);
        pmDataSet.setColor(android.graphics.Color.GREEN);
    }

    private void addEntry(float value, String type) {
        switch (type) {
            case "temperature":
                lineData.addEntry(new Entry(temperatureDataSet.getEntryCount(), value), 0);
                break;
            case "humidity":
                lineData.addEntry(new Entry(humidityDataSet.getEntryCount(), value), 1);
                break;
            case "pm":
                lineData.addEntry(new Entry(pmDataSet.getEntryCount(), value), 2);
                break;
        }
        lineData.notifyDataChanged();
        lineChart.notifyDataSetChanged();
        lineChart.setVisibleXRangeMaximum(20);
        lineChart.moveViewToX(lineData.getEntryCount() - 20);
    }

    private void addTestData() {
        for (int i = 0; i < 20; i++) {
            addEntry((float) (Math.random() * 30), "temperature");
            addEntry((float) (Math.random() * 100), "humidity");
            addEntry((float) (Math.random() * 200), "pm");
        }
    }

    private void showGasAlert() {
        new AlertDialog.Builder(this)
                .setTitle("报警")
                .setMessage("可燃气体浓度过高！请立即检查。")
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        // 在这里添加任何你想要的操作
                    }
                })
                .setIcon(android.R.drawable.ic_dialog_alert)
                .show();
    }

    @Override
    public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
        switch (compoundButton.getId()) {
            case R.id.parlour_light_switch:
                try {
                    if (compoundButton.isChecked()) {
                        mqttBinder.publishMessage("/test/light1", new Gson().toJson(new BoolMessage(true)));
                    } else {
                        mqttBinder.publishMessage("/test/light1", new Gson().toJson(new BoolMessage(false)));
                    }
                } catch (MqttException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.curtain_switch:
                try {
                    if (compoundButton.isChecked()) {
                        mqttBinder.publishMessage("/test/curtain1", new Gson().toJson(new BoolMessage(true)));
                    } else {
                        mqttBinder.publishMessage("/test/curtain1", new Gson().toJson(new BoolMessage(false)));
                    }
                } catch (MqttException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.fan_socket_switch:
                try {
                    if (compoundButton.isChecked()) {
                        mqttBinder.publishMessage("/test/fan1", new Gson().toJson(new BoolMessage(true)));
                    } else {
                        mqttBinder.publishMessage("/test/fan1", new Gson().toJson(new BoolMessage(false)));
                    }
                } catch (MqttException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.air_conditioning_switch:
                try {
                    if (compoundButton.isChecked()) {
                        String json = new Gson().toJson(new AirConfitioningMesssage(true, Float.parseFloat(airCconditioningValue.getText().toString())));
                        Log.d("json", json);
                        mqttBinder.publishMessage("/test/airConditionting", json);
                    } else {
                        String json = new Gson().toJson(new AirConfitioningMesssage(false, Float.parseFloat(airCconditioningValue.getText().toString())));
                        Log.d("json", json);
                        mqttBinder.publishMessage("/test/airConditionting", json);
                    }
                } catch (MqttException e) {
                    e.printStackTrace();
                }
                break;
        }
    }

    void unSubscribeTopics() {
        try {
            for (Map.Entry<String, Integer> entry : subscribeTopics.entrySet()) {
                mqttBinder.unSubscribe(entry.getKey());
            }
            subscribeTopics.clear();
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onConnectSuccess() {
        subscribeTopics();
        connectState.setText("已连接");
    }

    @Override
    public void onConnectError(String error) {
        Log.d(TAG, "onConnectError:" + error);
        connectState.setText("未连接");
        subscribeTopics.clear();
    }

    @Override
    public void onDeliveryComplete() {
        Log.d(TAG, "publish ok");
    }

    void subscribeTopics() {
        try {
            subscribeTopics.put("/test/temp", 1);
            subscribeTopics.put("/test/hum", 2);
            subscribeTopics.put("/test/pm", 3);
            subscribeTopics.put("/test/gas", 4);
            subscribeTopics.put("/test/door", 5);
            for (Map.Entry<String, Integer> entry : subscribeTopics.entrySet()) {
                mqttBinder.subscribe(entry.getKey());
            }
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onMqttMessage(String topic, String message) {
        Log.d("onMqttMessage", "topic:" + topic + "message length" + message.length() + ", message:" + message);
        Gson gson = new Gson();
        switch (subscribeTopics.get(topic)) {
            case 1:
                float temperature = gson.fromJson(message.trim(), FloatMessage.class).value;
                temperatureValue.setText(String.valueOf(temperature));
                addEntry(temperature, "temperature");
                break;
            case 2:
                int humidity = gson.fromJson(message.trim(), IntMessage.class).value;
                humidtyValue.setText(String.valueOf(humidity));
                addEntry(humidity, "humidity");
                break;
            case 3:
                int pm = gson.fromJson(message.trim(), IntMessage.class).value;
                pmValue.setText(String.valueOf(pm));
                addEntry(pm, "pm");
                break;
            case 4:
                int gas = gson.fromJson(message.trim(), IntMessage.class).value;
                gasValue.setText(String.valueOf(gas));
                if (gas > 100) { // 假设 100 是气体浓度过高的阈值
                    showGasAlert();
                }
                break;
            case 5:
                String status = gson.fromJson(message.trim(), BoolMessage.class).value ? "开" : "关";
                doorStatus.setText(status);
                break;
        }
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        if (mqttBinder.isConnected()) {
            connectState.setText("已连接");
            subscribeTopics();
        } else {
            connectState.setText("未连接");
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        unSubscribeTopics();
    }

    @Override
    protected void onDestroy() {
        unbindService(connection);
        super.onDestroy();
    }
}
